#pragma once
#include "baselist.hpp"
class ImageItem:public ListItem{
    SDL_Texture* _t;
    int w,h;
    public:
    ImageItem(SDL_Texture* t);
    void Draw(Renderer* render,ListState state,SDL_Rect& rect);
    ~ImageItem();
};
class TextItem:public ListItem{
    protected:
    SDL_Texture *_normal,*_select,*_on;
    int w,h;
    Font* font;
    const char* _text;
    SDL_Color on_color,select_color,normal_color;
    public:
    const char* text();
    TextItem(Window* window,const char* text,Font* font=default_font,SDL_Color normal_color=Color::Black,
    SDL_Color on_color=Color::Gray,SDL_Color select_color=Color::White);
    void Draw(Renderer* render,ListState state,SDL_Rect& rect);
    //将更新三个不同状态的文本缓存
    void SetText(Window* window,const char* text,Font* font=default_font,SDL_Color normal_color=Color::Black,
    SDL_Color on_color=Color::Gray,SDL_Color select_color=Color::White);
    ~TextItem()override;
};
class ListView:public BaseListView{
    protected:
    double _factor;//w/items->size()
    size_t select,on;
    Task* _task;
    SDL_Rect scroll;
    SDL_Color scroll_color,on_scroll_color,normal_scroll_color;
    bool _in;//鼠标是否进入
    static void ListenScroll(void* list);

    static void ListenMouse(void* list);
    public:
    int item_height,space;//每项高度和项间隔
    //未选中返回-1
    size_t selected();
    //rect的w必须比20大
    ListView(Window* window,SDL_Rect& rect,int space=2,int item_h=16,
    SDL_Color background=Color::Gray,SDL_Color select_color=Color::Blue,SDL_Color on_color=Color::SkyBlueGray,
    SDL_Color normal_scroll_color={0,0,0,120},SDL_Color on_scroll_color={0,0,0,220});
    ListView(Window* window);

    void ItemChanged()override;
    //w要大于5 不然显示会出问题
    void SetSize(int w,int h)override;
    void SetPosition(int x,int y)override;
    void OffsetPosition(int x,int y)override;

    ListItem* AddItem(ListItem* item)override;
    void AddItem(vector<ListItem*>* src)override;
    //越界抛出out_of_range 返回被移出的Item 需要手动析构
    ListItem* RemoveItem(size_t index);

    void _mouse_wheel(SDL_MouseWheelEvent& event);
    void _press(int x,int y,int clicks,unsigned char key);
    void _release(int x,int y,int clicks,unsigned char key);
    void _mouse_move(int x,int y);
    void _draw();
    void _key_down(SDL_Keysym& sym);
    ~ListView()override;
    void Clear(bool freed=true);
};
class TableItem:public ListItem{
    protected:
    public:
    vector<ListItem*> children;
    //空渲染，由TableView决定
    void Draw(Renderer* render,ListState state,SDL_Rect& rect);
    ~TableItem();
};
//必须添加的是TableItem，否则会出错
class TableView:public ListView{
    static void TableListenMouse(void* list);
    int spacex,item_w;
    size_t selectx,onx;
    public:
    TableView(Window* window,SDL_Rect& rect,int spacex=2,int spacey=2,int item_w=16,int item_h=16,
    SDL_Color background=Color::Gray,SDL_Color select_color=Color::Blue,SDL_Color on_color=Color::SkyBlueGray,
    SDL_Color normal_scroll_color={0,0,0,120},SDL_Color on_scroll_color={0,0,0,220});
    void _release(int x,int y,int clicks,unsigned char key);
    void _mouse_move(int x,int y);
    void _draw();
    ~TableView();
    void Clear(bool freed=true);
};
class TreeItem:public TextItem{
    protected:
    TreeItem* parent;
    vector<TreeItem*>* children;
    size_t extend_start;
    vector<ListItem*>* list;
    bool extend;
    unsigned int depth;
    int offset;//和
    int _offset;//单个
    //返回children个数，以便调整遍历次数
    void CollectCount(size_t& count);
    void ExtendOrFold();
    virtual void OnClick(int x,int y,unsigned char key)=0;
    virtual void OnDoubleClick(int x,int y,unsigned char key)=0;
    public:
    //使用时必须统一为TreeItem
    TreeItem(Window* window,const char* text,int extend_offset=10,
    Font* font=default_font,SDL_Color normal_color=Color::Black,
    SDL_Color on_color=Color::Gray,SDL_Color select_color=Color::White);
    //此方法中进行插入操作
    void OnAdd(vector<ListItem*>* l);
    TreeItem* Add(TreeItem* item);
    ~TreeItem()override;
    void _click(BaseListView* list,int x,int y,unsigned char key)override;
    void _double_click(BaseListView* list,int x,int y,unsigned char key)override;
    void Draw(Renderer* render,ListState state,SDL_Rect& rect);
    void UpdatePosition(long long n)override;
};

class TreeTextItem:public TreeItem{
    void OnClick(int x,int y,unsigned char key);
    void OnDoubleClick(int x,int y,unsigned char key);
    public:
    TreeTextItem(Window* window,const char* text,int extend_offset=10,
    Font* font=default_font,SDL_Color normal_color=Color::Black,
    SDL_Color on_color=Color::Gray,SDL_Color select_color=Color::White);
};